package com.iotp.service.role;

import com.iotp.dao.role.RoleDAO;
import com.iotp.dao.roleAuthorityRef.RoleAuthorityRefDAO;
import com.iotp.dao.roleMenuRef.RoleMenuRefDAO;
import com.iotp.entity.role.Role;
import com.iotp.entity.roleAuthorityRef.RoleAuthorityRef;
import com.iotp.entity.roleMenuRef.RoleMenuRef;
import com.iotp.service.base.BaseServiceImpl;
import com.iotp.utils.common.DataUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

/**
 * 系统角色业务接口实现类
 * @author Assassin
 */
@Service("roleService")
public class RoleServiceImpl extends BaseServiceImpl implements RoleService {

	// Fields

	@Autowired
	private RoleDAO roleDAO;// 系统角色DAO接口
	@Autowired
	private RoleMenuRefDAO roleMenuRefDAO;// 角色-菜单-关联DAO接口
	@Autowired
	private RoleAuthorityRefDAO roleAuthorityRefDAO;// 角色-权限-关联DAO接口
//	@Autowired
//	private CustomRealm customRealm;// 自定义Shiro Realm
	
	// Methods

   /**
	* 添加系统角色
	* @param roleType 标识信息-角色类型
	* @param orgId 标识信息-机构Id
	* @param orgCode 标识信息-机构编码
	* @param roleName 基本信息-角色名称
	* @param roleDesc 基本信息-角色说明
	* @param menuIds 系统菜单Ids
	* @param authorityIds 系统权限Ids
	* @return Long roleId 添加后的数据库主键值
	*/
	public Long add(Integer roleType, Long orgId, String orgCode, String roleName, String roleDesc, String menuIds, String authorityIds) {
		// 构造系统角色参数实体
		Role role = new Role();
		
		// 标识信息
		role.setRoleCode(DataUtil.getRoleCode(queryCurrentMaxRoleCode(orgId), orgCode));// Set 标识信息-角色编码
		role.setRoleType(roleType);// Set 标识信息-角色类型
		role.setOrgId(orgId);// Set 标识信息-机构Id
		
		// 状态信息
		role.setRoleStatus(1);// Set 状态信息-角色数据状态->默认数据状态=>1
		role.setIsDel(0);// Set 状态信息-是否删除[1-是 | 0-否]->默认是否删除=>0
		role.setRoleOrder(null);// Set 状态信息-角色排序->默认排序=>NULL
		
		// 基本信息
		role.setRoleName(roleName);// Set 基本信息-角色名称
		role.setRoleDesc(roleDesc);// Set 基本信息-角色说明
		
		// 时间信息
		Long createTime = System.currentTimeMillis();
		role.setCreateTime(createTime);// Set 时间信息-创建时间
		role.setUpdateTime(null);// Set 时间信息-更新时间[初始化=NULL]
		
		// 调用系统角色DAO接口
		this.roleDAO.insert(role);
		
		// 添加后的主键值
		Long roleId = role.getRoleId();
		
		// 角色添加成功、添加角色、菜单关联关系
		String[] menuIdsArr = menuIds.split(",");
		for(String menuId : menuIdsArr) {
			if(!menuId.equals("0")) {
				this.roleMenuRefDAO.insert(new RoleMenuRef(null, orgId, roleId, Long.parseLong(menuId)));
			}
		}
		
		// 角色添加成功、添加角色、权限关联关系
		String[] authorityIdsArr = authorityIds.split(",");
		for(String authorityId : authorityIdsArr) {
			if(!authorityId.equals("0")) {
				this.roleAuthorityRefDAO.insert(new RoleAuthorityRef(null, orgId, roleId, Long.parseLong(authorityId)));
			}
		}
		
		// 更新Ehcache缓存
//		this.relaodEhcache();
		
		// 返回添加后的主键值
		return role.getRoleId();
	}

   /**
	* 删除系统角色
	* @param roleId 主键值
	*/
	@Override
	public void delete(Long roleId) {
		// 调用系统角色DAO接口
		this.roleDAO.delete(roleId);
	}

  /**
	* 更新系统角色
	* @param roleId 标识信息-角色Id[主键值]
	* @param orgId 标识信息-机构Id
	* @param roleStatus 状态信息-角色数据状态
	* @param isDel 状态信息-是否删除[1-是 | 0-否]
	* @param roleOrder 状态信息-角色排序
	* @param roleName 基本信息-角色名称
	* @param roleDesc 基本信息-角色说明
	* @param menuIds 系统菜单Ids
	* @param authorityIds 系统权限Ids
	*/
	@Override
	public void edit(Long roleId, Long orgId, Integer roleStatus, Integer isDel, Integer roleOrder, String roleName, String roleDesc, String menuIds, String authorityIds) {
		// 构造系统角色参数实体
		Role role = new Role();
		role.setRoleId(roleId);// Set 标识信息-角色Id[主键值]
		role.setRoleStatus(roleStatus);// Set 状态信息-角色数据状态
		role.setIsDel(isDel);// Set 状态信息-是否删除[1-是 | 0-否]
		role.setRoleOrder(roleOrder);// Set 状态信息-角色排序
		role.setRoleName(roleName);// Set 基本信息-角色名称
		role.setRoleDesc(roleDesc);// Set 基本信息-角色说明
		role.setUpdateTime(System.currentTimeMillis());// Set 时间信息-更新时间[初始化=NULL]
		// 调用系统角色DAO接口
		this.roleDAO.update(role);
		
		// 角色编辑成功、编辑角色、菜单、权限关联关系
		
		// 检查菜单信息是否更新
		List<RoleMenuRef> menuRefList = this.roleMenuRefDAO.selectList(roleId);
		if(menuRefList == null || menuRefList.size() == 0) {
			String[] menuIdArr = menuIds.split(",");
			for(String menuId : menuIdArr) {
				if(!menuId.equals("0")) {
					this.roleMenuRefDAO.insert(new RoleMenuRef(null, orgId, roleId, Long.parseLong(menuId)));
				}
			}
		} else {
			String currMenuIds = "";
			for(RoleMenuRef ref : menuRefList) {
				currMenuIds += ref.getMenuId().longValue() + ",";
			}
			String[] currMenuArr = currMenuIds.split(",");
			String[] menuIdArr = menuIds.split(",");
			if(!Arrays.equals(currMenuArr, menuIdArr)) {
				this.roleMenuRefDAO.delete(roleId);
				for(String menuId : menuIdArr) {
					if(!menuId.equals("0")) {
						this.roleMenuRefDAO.insert(new RoleMenuRef(null, orgId, roleId, Long.parseLong(menuId)));
					}
				}
			}
		}
		
		// 检查权限信息是否更新
		List<RoleAuthorityRef> refList = this.roleAuthorityRefDAO.selectList(roleId);
		if(refList == null || refList.size() == 0) {
			String[] authorityIdArr = authorityIds.split(",");
			for(String authorityId : authorityIdArr) {
				if(!authorityId.equals("0")) {
					this.roleAuthorityRefDAO.insert(new RoleAuthorityRef(null, orgId, roleId, Long.parseLong(authorityId)));
				}
			}
		} else {
			String currAuthorityIds = "";
			for(RoleAuthorityRef ref : refList) {
				currAuthorityIds += ref.getAuthorityId().longValue() + ",";
			}
			String[] currAuthorityArr = currAuthorityIds.split(",");
			String[] authorityIdArr = authorityIds.split(",");
			if(!Arrays.equals(currAuthorityArr, authorityIdArr)) {
				this.roleAuthorityRefDAO.delete(roleId);
				for(String authorityId : authorityIdArr) {
					if(!authorityId.equals("0")) {
						this.roleAuthorityRefDAO.insert(new RoleAuthorityRef(null, orgId, roleId, Long.parseLong(authorityId)));
					}
				}
			}
		}
		// 更新Ehcache缓存
//		this.relaodEhcache();
	}

   /**
	* 主键查询系统角色
	* @param -role 参数实体
	* @return Role 实体
	*/
	@Override
	public Role queryById(Long roleId) {
		// 调用系统角色DAO接口
		return this.roleDAO.selectById(roleId);
	}

   /**
	* 根据条件查询系统角色列表
	* @param roleId 标识信息-角色Id[主键值]
	* @param roleCode 标识信息-角色编码
	* @param roleType 标识信息-角色类型
	* @param orgId 标识信息-机构Id
	* @param roleStatus 状态信息-角色数据状态
	* @param isDel 状态信息-是否删除[1-是 | 0-否]
	* @param roleOrder 状态信息-角色排序
	* @param roleName 基本信息-角色名称
	* @param roleDesc 基本信息-角色说明
	* @param createTime 时间信息-创建时间
	* @param updateTime 时间信息-更新时间[初始化=NULL]
	* @return List<Role> 实体List
	*/
	@Override
	public List<Role> queryList(Long roleId, String roleCode, Integer roleType, Long orgId, Integer roleStatus, Integer isDel, Integer roleOrder, String roleName, String roleDesc, Long createTime, Long updateTime) {
		// 构造系统角色参数实体
		Role role = new Role();
		role.setRoleId(roleId);// Set 标识信息-角色Id[主键值]
		role.setRoleCode(roleCode);// Set 标识信息-角色编码
		role.setRoleType(roleType);// Set 标识信息-角色类型
		role.setOrgId(orgId);// Set 标识信息-机构Id
		role.setRoleStatus(roleStatus);// Set 状态信息-角色数据状态
		role.setIsDel(isDel);// Set 状态信息-是否删除[1-是 | 0-否]
		role.setRoleOrder(roleOrder);// Set 状态信息-角色排序
		role.setRoleName(roleName);// Set 基本信息-角色名称
		role.setRoleDesc(roleDesc);// Set 基本信息-角色说明
		role.setCreateTime(createTime);// Set 时间信息-创建时间
		role.setUpdateTime(updateTime);// Set 时间信息-更新时间[初始化=NULL]
		// 调用系统角色DAO接口
		return this.roleDAO.selectList(role);
	}
	
	/**
	 * 编辑角色状态（逻辑删除 | 恢复）
	 * @param roleId 角色Id
	 * @param isDel 是否删除状态
	 */
	@Override
	public void editIsDel(Long roleId, Integer isDel) {
		// 逻辑删除
		if(isDel.intValue() == 1) {
			HashMap<String, Object> paramsMap = new HashMap<String, Object>();
			paramsMap.put("roleId", roleId);
			paramsMap.put("isDel", isDel);
			paramsMap.put("updateTime", System.currentTimeMillis());
			this.roleDAO.updateIsDel(paramsMap);
		}
	}
	
	/**
	 * 查询用户的角色信息
	 * @param userId 用户Id
	 * @return List<Role>
	 */
	@Override
	public List<Role> queryRoleByUserId(Long userId) {
		return this.roleDAO.selectRoleByUserId(userId);
	}
	
	/**
	 * 根据属性验证角色是否存在
	 * @param orgId 机构Id
	 * @param roleId 角色Id
	 * @param roleName 角色名称
	 * @return List<Role>
	 */
	@Override
	public List<Role> queryIsRoleExist(Long orgId, Long roleId, String roleName) {
		HashMap<String, Object> paramsMap = new HashMap<String, Object>();
		paramsMap.put("orgId", orgId);
		paramsMap.put("roleId", roleId);
		paramsMap.put("roleName", roleName);
		return this.roleDAO.selectIsRoleExist(paramsMap);
	}
	
	/**
	 * 根据机构Id查询当前数据库角色最大编码
	 * @param orgId 机构Id
	 * @return currentMaxRoleCode
	 */
	private String queryCurrentMaxRoleCode(Long orgId) {
		return this.roleDAO.selectCurrentMaxRoleCode(orgId);
	}
	
	/**
	 * 重新加载Ehcache缓存
	 */
//	private void relaodEhcache() {
		// 更新Ehcache缓存
//		this.customRealm.clearAllCache();
//	}
	
}